home *** CD-ROM | disk | FTP | other *** search
/ New Star Software Collection / NSS_Collection.iso / 3-170 dbase 10 for windows / 1.ima / DOC.PAK / DLL_API.TXT < prev    next >
Text File  |  1993-07-26  |  12KB  |  332 lines

  1.       Copyright (c) 1991-1993 Borland International, Inc.
  2.                     All Rights Reserved.
  3.  
  4.  
  5.           CALLING DLL FUNCTIONS AND THE WINDOWS API
  6.           -----------------------------------------
  7.  
  8.  
  9. Dynamic-link libraries (DLLs) are files containing compiled
  10. program code that Windows applications load and execute at
  11. runtime.  Through DLLs, your Bladerunner application can call
  12. non-dBASE functions, such as C and Pascal functions.
  13.  
  14. The Windows API (application programming interface) is a library
  15. of C functions contained in DLLs.  This document introduces
  16. dynamic linking to dBASE programmers and shows how to call non-
  17. dBASE functions from DLLs and the Windows API.
  18.  
  19. Contents
  20. --------
  21. I.   About Libraries and Linking
  22. II.  Calling DLL Functions
  23. III. Calling Windows API Functions
  24.  
  25. About Libraries and Linking
  26. ---------------------------
  27.  
  28. The terms "library" and "linking" mean different things to
  29. different programmers.  dBASE III PLUS developers maintain
  30. libraries of often-used routines and incorporate them into
  31. applications without linking.  dBASE IV developers use
  32. DBLINK to link compiled programs and library routines into
  33. one large object file.
  34.  
  35. C language developers perform "static linking" when they
  36. create an executable file from various object modules and
  37. run-time libraries.  Static linking occurs just once at the
  38. time you create an application. In contrast, Windows
  39. applications perform "dynamic linking" by calling routines
  40. and resources at run time.  Dynamic linking occurs many
  41. times while an application is running.  Since DLLs are parts
  42. of applications, they must be present on the disk when a
  43. program calls one of their routines or resources.
  44.  
  45. By maintaining compiled routines and resources in separate
  46. files, and linking them to applications at run time:
  47.  
  48. o  You can share the same library among many applications,
  49.    even among two applications running concurrently in
  50.    Windows 386 enhanced mode.
  51.  
  52. o  You don't have to recompile or relink the library every
  53.    time you build your application.
  54.  
  55. o  You create smaller executable files.
  56.  
  57. Calling DLL Functions
  58. ---------------------
  59.  
  60. Using DLLs is much like using procedure files.  You load a DLL
  61. into memory before using one of its routines, then release the
  62. DLL when its routines are no longer needed.  If the DLL file has
  63. a .DLL extension, or is part of the WIndows API, Bladerunner loads 
  64. the file automatically; otherwise you need to explicitly load the 
  65. file with LOAD DLL. (LOAD DLL is not implemented in this Alpha
  66. release; you can use the Windows API function LoadLibrary() 
  67. instead.)
  68.  
  69. Since DLLs are loaded at runtime, DLL files must be present on disk
  70. at runtime.
  71.  
  72. You need to declare a "prototype" for each non-dBASE function
  73. before you call the function.  A prototype specifies the data
  74. type for the function's parameters and return value.  You declare
  75. prototypes with the EXTERN command.
  76.  
  77. The need for prototypes becomes apparent when you consider
  78. the problem of passing parameters into functions of
  79. different languages.  Bladerunner uses prototypes to
  80. convert the data types of parameters and return values
  81. automatically.  For instance, when you call a C function,
  82. Bladerunner automatically converts the parameters from
  83. dBASE data types into C data types, and then converts the
  84. return values from C back into dBASE.
  85.  
  86. Follow these steps to call DLL functions:
  87.  
  88. 1. If the DLL file does not have a .DLL extension, and is not part
  89.    of the Windows API, you need to load the DLL file into memory with 
  90.    LOAD DLL. (Note: In this Alpha release, LOAD DLL is not yet 
  91.    implemented. You can use the Windows API function LoadLibrary() 
  92.    instead.) 
  93.  
  94.    If the DLL file has a .DLL extension, you can skip this step.
  95.  
  96. 2. Prototype the non-dBASE functions with EXTERN.
  97.  
  98. 3. Call the non-dBASE functions right in your dBASE code.
  99.  
  100. 4. Remove the DLL file from memory with RELEASE DLL.
  101.  
  102.  
  103.  
  104. EXTERN prototypes non-dBASE functions.  Here is the syntax:
  105.  
  106. EXTERN [CDECL] <cType1> <function name> ([<cType2>, ...])<dll name>
  107.  
  108. These are the options for EXTERN:
  109.  
  110. [CDECL] -- Tells dBASE to use the C language calling convention,
  111. instead of the default Pascal calling convention, so you can pass
  112. additional parameters beyond those specified in the declaration
  113. for this function.
  114.  
  115. <cType1> -- Specifies the return value's data type. All EXTERN 
  116. functions have to specify a return type even if it is CVOID.
  117.  
  118. <cType2> -- Optionally specifies the data type of each parameter. 
  119.  
  120. All arguments need to match their declared type as follows:
  121.  
  122. Data Type     Keyword     API Data Type
  123. ---------     -------     -------------
  124. Numeric       CWORD       unsigned int   (16 bit)
  125. Numeric       CLONG       unsigned long  (32 bit)
  126. Numeric       CDOUBLE     double float   (64 bit double)
  127. Character     CPTR        char far *     (string)
  128. N/A           CVOID       void
  129.  
  130. <function name> -- The name of the function in the DLL.
  131.  
  132. <dll name> -- The name of the Windows .DLL that contains the
  133. function.
  134.  
  135. Note: Most of the functionality of Windows is contained in DLL's,
  136. but dynamic link library code can also be present in .EXE files
  137. (or even in .DRV or .FON files).
  138.  
  139. Example:
  140.  
  141.      EXTERN CWORD MessageBox(CWORD,CPTR,CPTR,CWORD) user.exe
  142.  
  143. Calling Windows API Functions
  144. -----------------------------
  145.  
  146. The API function must be prototyped before you call it from 
  147. Bladerunner.  You can prototype the API functions at the Command
  148. window, in the .PRG, or in an #include file.  Once an API
  149. function has been prototyped, it is available as if it were an
  150. internal Bladerunner function, until you end that Bladerunner
  151. session.
  152.  
  153. Execute the API function like any dBASE function after you have
  154. prototyped it.  API functions can be called directly or they can
  155. be part of a dBASE expression or function.  Also, dBASE functions
  156. can be put inside API functions.
  157.  
  158. Example:
  159.  
  160.       EXTERN CWORD MessageBox(CWORD,CPTR,CPTR,CWORD) user.exe
  161.       ? MessageBox(0,"My Text","From Windows",17)
  162.  
  163.       or
  164.  
  165.       pressed = MessageBox(0,"My Text","From Windows",17)
  166.  
  167.       or
  168.  
  169.       ? MessageBox(0,"My Text","From Windows",HTOI("00011"))
  170.  
  171. This displays a Windows MessageBox in the middle of the screen,
  172. with the Title: "From Windows" and the Message: "My Text" and two
  173. buttons: "OK" "CANCEL" and the ICON: "STOP".  It returns the
  174. value for the button pressed 1= OK , 2 = CANCEL.
  175.  
  176. Note: You can execute the function without the ? (print) command,
  177. just by putting the function name with its arguments on the
  178. command line by itself, but you won't display the return value.
  179.  
  180. Example:
  181.  
  182.       EXTERN CWORD MessageBox(CWORD,CPTR,CPTR,CWORD) user.exe
  183.       MessageBox(0,"My Text","From Windows",17)
  184.  
  185. Displays MessageBox as above but without displaying the return
  186. value for the button pressed.
  187.  
  188. The windows API functions can be prototyped and executed right at
  189. the command window in Bladerunner.  You do not have to load any
  190. special header file or .DLL to access the windows API functions.
  191.  
  192. API Window Handles
  193.  
  194. API window handles are numbers, 16 bit integers (CWORD), like
  195. file handles in DOS, that are assigned to every window.  To get
  196. the Windows handle of dBASEWIN.EXE you can use the following
  197. approaches:
  198.  
  199. Example A:
  200.  
  201.       hDBW = _APP.FRAMEWIN.HWND
  202.  
  203. The variable hDBW now holds the Windows handle to dBASEWIN.EXE
  204. FRAMEWIN (the main window of dBASEWIN.EXE).
  205.  
  206. Example B:
  207.  
  208.       EXTERN CWORD GetActiveWindow( ) user.exe
  209.       hDBW = GetActiveWindow( )
  210.  
  211. The variable hDBW now holds the windows handle of the active
  212. window.  If you type the above in the Command window, the
  213. variable hDBW will hold the Windows handle of the FRAMEWIN of
  214. dBASEWIN.EXE, as in Example A, above.
  215.  
  216. Example C:
  217.  
  218.       EXTERN CWORD GetFocus() user.exe
  219.       hDBW = GetFocus()
  220.  
  221. The variable hDBW now holds the windows handle of the window with
  222. input focus.  If you type the above in the Command window, the
  223. variable hDBW will hold the Windows handle of the Command window.
  224. But if you DEFINE a window and ACTIVATE the window, then issue
  225. the GetFocus() function in your program, it will return the
  226. handle of the window you ACTIVATED.
  227.  
  228. Windows API Constants
  229.  
  230. Windows has many constants defined as integers, like the cursors
  231. below.
  232.  
  233. Example:
  234.  
  235.       #define IDC_ARROW       (32512)
  236.       #define IDC_IBEAM       (32513)
  237.       #define IDC_WAIT        (32514)
  238.       #define IDC_CROSS       (32515)
  239.       #define IDC_UPARROW     (32516)
  240.       #define IDC_SIZE        (32640)
  241.       #define IDC_ICON        (32641)
  242.       #define IDC_SIZENWSE    (32642)
  243.       #define IDC_SIZENESW    (32643)
  244.       #define IDC_SIZEWE      (32644)
  245.       #define IDC_SIZENS      (32645)
  246.       EXTERN CWORD LoadCursor(CWORD,CWORD) user.exe
  247.       EXTERN CWORD SetCursor(CWORD) user.exe
  248.       orgcsr = SetCursor(LoadCursor(0, IDC_ICON))
  249.          FOR  x = 1 to 210000
  250.          NEXT
  251.       SetCursor(orgcsr)
  252.  
  253. HEX Numbers
  254.  
  255. Windows has many constants defined as hex numbers.
  256.  
  257. Example:
  258.  
  259.       #define MB_OK                 0x0000
  260.       #define MB_OKCANCEL           0x0001
  261.       #define MB_ABORTRETRYIGNORE   0x0002
  262.       #define MB_YESNOCANCEL        0x0003
  263.       #define MB_ICONHAND           0x0010
  264.       #define MB_ICONQUESTION       0x0020
  265.       #define MB_ICONEXCLAMATION    0x0030
  266.       #define MB_ICONASTERISK       0x0040
  267.       EXTERN CWORD MessageBox(CWORD,CPTR,CPTR,CWORD) user.exe
  268.       MessageBox(0,"My Text","From Windows",HTOI("0x0022"))
  269.  
  270. The dBASE functions for working with hex numbers are:
  271.  
  272.       HTOI() Takes a hex number as a string and returns an
  273.              integer.
  274.       ITOH() Takes an integer and returns a hex number as a
  275.              string.
  276.  
  277. Bits
  278.  
  279. Many DLL functions interpret individual bits in an integer
  280. argument or return value.  We have added several new functions to
  281. Bladerunner for working with bits.  Bits are numbered in an
  282. integer from the least significant bit (rightmost) to the most
  283. significant bit (leftmost).  Bit numbering starts at 0 (see
  284. example below).
  285.  
  286.      Most                                  Least
  287.      Significant                           Significant
  288.       15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
  289.      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  290.  
  291. Example:
  292.  
  293.    * gVer.prg
  294.    #define HiWord(x) (bitrshift(bitand(x,4294901760),16))
  295.    #define LoWord(x) (bitand(x,65535))
  296.    #define HiByte(x) (ltrim(str(bitrshift(bitand(x,65280),8))))
  297.    #define LoByte(x) (ltrim(str(bitand(x,255))))
  298.    EXTERN CLONG GetVersion( ) krnl386.exe
  299.    z=GetVersion( )
  300.    RETURN "DOS version;
  301.       "+HiByte(HiWord(z))+"."+LoByte(HiWord(z))+ ;
  302.       ", Windows version"+LoByte(LoWord(z))+"."+HiByte(LoWord(z))
  303.  
  304. Note: The above code example, and several others, are included
  305. with the sample code provided with this Alpha release.
  306.  
  307. The new dBASE bit functions are: BitAND(), BitLshift(),
  308. BitRshift(), BitOr(), BitXor(),and BitSet().
  309.  
  310. Windows API Strings
  311.  
  312. Many API functions take a string as an argument.  Some API
  313. functions only want a Pointer (a reference) to a string that the
  314. function can fill with the returned information.  In this case
  315. you need to make the string large enough to hold the result (some
  316. also require you to pass the length of the string as a argument).
  317.  
  318. Example:
  319.  
  320.       dBWhand = _APP.FRAMEWIN.HWND
  321.       EXTERN CWORD GetWindowText(CWORD,CPTR,CWORD) user.exe
  322.       winTitle = SPACE(80)
  323.       && first make empty string to be filled
  324.       lenTitle = GetWindowText(dBWhand,winTitle,80)
  325.       ? winTitle
  326.  
  327. Note: With Bladerunner's object-oriented language extensions you
  328. can get the same information with this command:
  329.  
  330.       ? _APP.FRAMEWIN.CAPTION
  331.  
  332.